package cc.verywell.pureblock.net;

import java.io.IOException;
import java.net.SocketAddress;

import cc.verywell.pureblock.func.FuncList;
import cc.verywell.pureblock.log.Pblog;
import cc.verywell.pureblock.net.NormalChannel.CloseState;

/**
* 
* Copyright 2019 TanYaqiu
* @author TanYaqiu 
* @address flat 601
* @date 2019年3月14日 下午10:51:26
*/
public class NormalSession {

	private NormalChannel channel;
	final public int salt;
	public NormalSession(NormalChannel channel, int salt) {
		this.channel = channel;
		this.salt = salt;
		this.timelog = AioProvider.timelog.getTimelog(this);//要先保证channel已经可以运作了; 
	}
	public synchronized void clear() {
		this.channel = null;
	}
	public synchronized NormalChannel getChannel() {
		return channel;
	}
	@Override
	public String toString() {
		NormalChannel nc = getChannel();
		if(nc!=null && nc.getSession()==this)return nc.toString();
		return Integer.toHexString(salt)+"->"+nc;
	}
	
	public boolean writeMsg(Msg msg) {
		NormalChannel channel = getChannel();
		if(channel!=null) {
			return channel.write(msg);
		}else {
			msg.failed(null, this);
			return false;
		}
	}
	
	public void close() {
		NormalChannel channel = getChannel();
		if(channel!=null)channel.close(false);
	}
	public boolean isClosed() {
		NormalChannel channel = getChannel();
		return !(channel!=null && channel.closeState==CloseState.Normal);
	}
	public void timeout() {
		NormalChannel channel = getChannel();
		if(channel!=null)channel.getContext().sessionTimeout(this);
	}
	public void startRead() {
		NormalChannel channel = getChannel();
		if(channel!=null)channel.startRead();
	}
	
	public SocketAddress getRemote() {
		NormalChannel channel = getChannel();
		if(channel!=null) {
			try {
				return channel.getChannel().getRemoteAddress();
			} catch (IOException e) {
				if(Pblog.IO)Pblog.IO(e);
			}
		}
		return null;
	}
	private boolean init = false;
	public void annouceInited() {
		synchronized(this) {
			if(init)throw new IllegalAccessError();
			init=true;
		}
		NormalChannel channel = getChannel();
		if(channel!=null)channel.getCallback().init(this);
	}
	
	private FuncList funcList;
	public void setFunc(FuncList funcList) {
		this.funcList = funcList;
	}
	public FuncList getFunc() {
		return this.funcList;
	}
	
	final private Timelog timelog;
	public Timelog getTimelog() {
		return timelog;
	}
	
}
